#include <func.h>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include "Crypto.h"

const unsigned char key[33] = "CloudDisk.KEY";  
const unsigned char iv[17] = "CloudDisk.IV";    

// 禁用终端回显
void disable_echo(int fd, struct termios* old_termios) 
{
    struct termios new_termios;
    tcgetattr(fd, old_termios);
    new_termios = *old_termios;
    new_termios.c_lflag &= ~ECHO;
    tcsetattr(fd, TCSANOW, &new_termios);
}

// 恢复终端回显
void restore_echo(int fd, struct termios* old_termios)
{
    tcsetattr(fd, TCSANOW, old_termios);
}

int aes256_encrypt(const unsigned char* plaintext, int plaintext_len, 
                   unsigned char* ciphertext)
{
    EVP_CIPHER_CTX* context = EVP_CIPHER_CTX_new();     // 创建上下
    // 初始化 AES-256-CBC 加密
    EVP_EncryptInit_ex(context, EVP_aes_256_cbc(), NULL, key, iv); 
    
    // 加密
    int len, ciphertext_len;
    EVP_EncryptUpdate(context, ciphertext, &len, plaintext, plaintext_len);
    ciphertext_len = len;
    // 处理填充部分
    EVP_EncryptFinal_ex(context, ciphertext + len, &len);
    ciphertext_len += len;

    EVP_CIPHER_CTX_free(context);
    return ciphertext_len;
}

int aes256_decrypt(const unsigned char* ciphertext, int ciphertext_len, 
                   unsigned char* plaintext)
{
    EVP_CIPHER_CTX* context = EVP_CIPHER_CTX_new(); // 创建上下文
    
    int len, plaintext_len;
    // 初始化 AES_256_CBC 解密
    EVP_DecryptInit_ex(context, EVP_aes_256_cbc(), NULL, key, iv);
    // 解密
    EVP_DecryptUpdate(context, plaintext, &len, ciphertext, ciphertext_len);
    plaintext_len = len;

    // 处理填充部分
    EVP_DecryptFinal_ex(context, plaintext + len, &len);
    plaintext_len += len;

    EVP_CIPHER_CTX_free(context);
    return plaintext_len;
}

#ifdef TEST_CRYPTO
int main(int argc, char* argv[]) 
{
    char username[26];
    char passwd[26];
    char confirm[26];
    printf("用户名: ");
    scanf("%s", username);
    printf("密码: ");

    // 禁用回显
    struct termios old_termios;
    disable_echo(STDIN_FILENO, &old_termios);

    scanf("%s", passwd);
    printf("\n");
    printf("确认密码: ");
    scanf("%s", confirm);
    printf("\n");

    // 恢复回显
    restore_echo(STDIN_FILENO, &old_termios);
    printf("再次输入密码：");
    scanf("%s", confirm);
    printf("\n");

    if (strcmp(passwd, confirm) != 0) {
        printf("密码不一致, 请重新输入!\n");
        return 0;
    }
    
    unsigned char ciphername[1024];
    unsigned char decryptname[1024];
    int ctext_len = aes256_encrypt(username, strlen(username), ciphername); 
    int dtext_len = aes256_decrypt(ciphername, ctext_len, decryptname);
    decryptname[dtext_len] = '\0';
    printf("decryptname: %s\n", decryptname);

    unsigned char cipherpasswd[1024];
    unsigned char decryptpasswd[1024];
    ctext_len = aes256_encrypt(passwd, strlen(username), cipherpasswd); 
    dtext_len = aes256_decrypt(cipherpasswd, ctext_len, decryptpasswd);
    decryptpasswd[dtext_len] = '\0';
    printf("decryptpasswd: %s\n", decryptpasswd);
    return 0;
}

#endif
